#ifndef PLAYER_H
#define PLAYER_H

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <SDL2/SDL.h>
}
#include <queue>

//版本号
#define VERSION "0.1v\n"
//音频单帧最大字节数
#define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
//播放器命名空间
namespace player
{
//控制音频播放结构体，主要传递音频数据到音频播放回调函数
typedef struct AUDIOBUFCTRL
{
    //音频播放缓冲区首地址
    unsigned char *pAudioChunk;
    //当前播放音频数据首指针
    unsigned char *pAudioPos;
    //当前播放剩余音频数据长度
    unsigned int audioLen;
}AudioBufCtrl;
//音频转换后输出格式
typedef struct AUDIOOUTFMT
{  
    //输出单个通道采样数据字节数
    int outNbSamples;
    //输出采样率
    int outSamplesRate;
    //输出通道数
    int outChannels;
    //输出帧大小
    int outFrameSize;
    //输出通道格式
    unsigned long outChLayout;
    //采用格式
    AVSampleFormat outNbSampleFmt;
}AudioOutFmt;
// 视频转换后输出格式
typedef struct VIDEOOUTFMT
{
    //视频转换后的输出帧
    AVFrame *pOutFrame;
}VideoOutFmt;
//音视频编解码器相关变量
typedef struct CODEC
{
    //编解码器上下文
    AVCodecContext *pCodeCtx;
    //编解码器
	const AVCodec *pAvCodec;
    //单个音频/视频帧
    AVFrame	*pFrame;
    //音频格式转换上下文
    struct SwsContext *pSwsConvertCtx;
    //视频格式转换上下文
    struct SwrContext *pSwrConvertCtx;
    //音视频数据缓存
    unsigned char *pBuffer;
    //音频转换输出格式
    AudioOutFmt *pAudioOutFmt;
    //音频播放控制结构体
    AudioBufCtrl audioBufCtrl;
    //视频转换输出格式(其实是转换输出缓存)
    VideoOutFmt videoOutFmt;
}Codec;
//播放器类
class Player
{
public:
    //输入文件名
    char *filename;
    //event线程结束标志
    bool isEventClose;
    //格式化上下文
    AVFormatContext	*pFormatCtx;
    //数据包
    AVPacket *pPacket;
    //音视频编解码器
    Codec *pCodec;
    //构造函数
    Player(const char *file);
    //析构函数
    ~Player();
    //打印版本
    int versionShow(void);
    //初始化
    int init(void);
    //退出初始化i
    int exit(void);
    //事件线程循环
    static int eventLoop(void *pthis);
    //解包线程循环
    static int unpackLoop(void *pthis);
    //音频播放循环
    static int audioLoop(void *pthis);
    //视频播放循环
    static int videoLoop(void *pthis);
    //音频播放回调
    static void audioCallBack(void *pthis,unsigned char *stream,int len);
    //编解码器初始化，每个流对应一个
    int codecContextInit(int streamIndex);
    //编解码器关闭
    int codecContextExit(int streamIndex);
private:
    //窗口是否关闭
    bool isClose;
    //解包线程是否结束
    bool isUnpackClose;
    //音频线程是否结束
    bool isAudioClose;
    //视频线程是否结束
    bool isVideoClose;
    //窗口宽度
    int screenW;
    //窗口高度
    int screenH;
    //音频流索引
    int audioStreamIndex;
    //视频流索引
    int videoStreamIndex;
    //获取音频帧状态
    int gotAudioPicture;
    //获取视频帧状态
    int gotVideoPicture;
    //互斥量
    SDL_mutex *pMutex;
    //事件线程指针
    SDL_Thread *eventThread;
    //解包线程指针
    SDL_Thread *unpackThread;
    //音频线程指针
    SDL_Thread *audioPlayerThread;
    //视频线程指针
    SDL_Thread *videoPlayerThread;
    //键盘事件处理
    int keyEvent(int key);
};    
} // namespace audioPlayer


#endif



